package graphics.raytracing;

import static util.MatrixOperationsF.*;
import util.MatrixOperationsF;

public class Triangle implements Tracable {
	float[][] _coords;
	private CastResult intersectBuffer;
	private boolean done=false;
	private boolean inters;

	public Triangle(float[][] triangle) {
		_coords = cloo(triangle);
	}

	

	public boolean intersects(Ray ray) {
		return cast(ray)!=null;
	}

	@Override
	public CastResult cast(Ray ray) {
		float[] hit = determine_hit_location(ray);
		if(hit[0]<0||hit[0]>1)
			return null;
		if(hit[1]<0||hit[1]>1)
			return null;
		
	return		new CastResult(this, add(ray.getOrigin(),multiply(ray.getDirection(),determine_hit_location(ray)[2])),getNormal());
	}
	private float[] getNormal() {
		return cross_product(add(_coords[1],negate(_coords[0])), add(_coords[2],negate(_coords[0])));
	}



	/**
	 * 
	 * @param ray
	 * @return {Beta,Gamma,t}
	 */
	public float[] determine_hit_location(Ray ray) {
		final int x =0;
		final int y =1;
		final int z =2;
		float[] a = _coords[0];
		float[] b = _coords[1];
		float[] c = _coords[2];
		float[] eye = ray.getOrigin();
		float[] direction = ray.getDirection();
		//magic, it works, dont figure it out
		float _a = a[x]-b[x];
		float _b = a[y]-b[y];
		float _c = a[z]-b[z];
		float _d = a[x]-c[x];
		float _e = a[y]-c[y];
		float _f = a[z]-c[z];
		float _g=direction[x];
		float _h=direction[y];
		float _i=direction[z];
		float _j=a[x]-eye[x];
		float _k=a[y]-eye[y];
		float _l=a[z]-eye[z];
		float M = _a*(_e*_i-_h*_f)+_b*(_g*_f-_d*_i)+_c*(_d*_h-_e*_g);
 		float beta=( _j*(_e*_i-_h*_f)+_k*(_g*_f-_d*_i)+_l*(_d*_h-_e*_g))/M;
 		float gamm =( _i*(_a*_k-_j*_b)+_h*(_j*_c-_a*_l)+_g*(_b*_l-_k*_c))/M;
 		float t = -(_f*(_a*_k-_j*_b)+_e*(_j*_c-_a*_l)+_d*(_b*_l-_k*_c))/M;
		return ar(beta,gamm,t);
	}
	@Override
	public String toString()
	{
		return print(_coords[0])+print(_coords[1])+print(_coords[2]);
	}

}
